From b99cb70299e9a5148556540dc584ea5535241a6e Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 18 Sep 2017 07:34:46 -0400 Subject: [PATCH] css: Implement font-variant-numeric This gets translated to the corresponding OpenType features. --- gtk/gtkcssstyle.c | 24 ++++++++++ gtk/gtkcssstylepropertyimpl.c | 87 +++++++++++++++++++++++++++++++++++ gtk/gtkcsstypesprivate.h | 1 + 3 files changed, 112 insertions(+) diff --git a/gtk/gtkcssstyle.c b/gtk/gtkcssstyle.c index 8b35f0e5ce..33960349d8 100644 --- a/gtk/gtkcssstyle.c +++ b/gtk/gtkcssstyle.c @@ -229,6 +229,7 @@ gtk_css_style_get_pango_attributes (GtkCssStyle *style) GtkCssValue *ligatures; GtkCssValue *position; GtkCssValue *caps; + GtkCssValue *numeric; GString *s; int i; @@ -345,6 +346,29 @@ gtk_css_style_get_pango_attributes (GtkCssStyle *style) g_string_append (s, "titl 1"); } + numeric = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC); + for (i = 0; i < _gtk_css_array_value_get_n_values (numeric); i++) + { + GtkCssValue *value = _gtk_css_array_value_get_nth (numeric, i); + if (s->len > 0) g_string_append (s, ", "); + if (strcmp (_gtk_css_ident_value_get (value), "lining-nums") == 0) + g_string_append (s, "lnum 1"); + else if (strcmp (_gtk_css_ident_value_get (value), "oldstyle-nums") == 0) + g_string_append (s, "onum 1"); + else if (strcmp (_gtk_css_ident_value_get (value), "proportional-nums") == 0) + g_string_append (s, "pnum 1"); + else if (strcmp (_gtk_css_ident_value_get (value), "tabular-nums") == 0) + g_string_append (s, "tnum 1"); + else if (strcmp (_gtk_css_ident_value_get (value), "diagonal-fractions") == 0) + g_string_append (s, "frac 1"); + else if (strcmp (_gtk_css_ident_value_get (value), "stacked-fractions") == 0) + g_string_append (s, "afrc 1"); + else if (strcmp (_gtk_css_ident_value_get (value), "ordinal") == 0) + g_string_append (s, "ordn 1"); + else if (strcmp (_gtk_css_ident_value_get (value), "slashed-zero") == 0) + g_string_append (s, "zero 1"); + } + attrs = add_pango_attr (attrs, pango_attr_font_features_new (s->str)); g_string_free (s, TRUE); diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c index 12b4f3ce15..a0311b37b0 100644 --- a/gtk/gtkcssstylepropertyimpl.c +++ b/gtk/gtkcssstylepropertyimpl.c @@ -657,6 +657,85 @@ parse_font_variant_caps (GtkCssStyleProperty *property, return value; } +static GtkCssValue * +parse_font_variant_numeric (GtkCssStyleProperty *property, + GtkCssParser *parser) +{ + GtkCssValue *value = NULL; + + if (_gtk_css_parser_try (parser, "normal", TRUE)) + value = _gtk_css_array_value_new (_gtk_css_ident_value_new ("normal")); + else + { + GtkCssValue *values[5] = { NULL, NULL, NULL, NULL }; + guint n_values = 0; + guint old_n; + gboolean figure = FALSE; + gboolean spacing = FALSE; + gboolean fraction = FALSE; + gboolean ordinal = FALSE; + gboolean zero = FALSE; + + do { + old_n = n_values; + if (!figure) + { + values[n_values] = _gtk_css_ident_value_try (parser, "lining-nums", "oldstyle-nums", NULL); + if (values[n_values]) + { + n_values++; + figure = TRUE; + } + } + if (!spacing) + { + values[n_values] = _gtk_css_ident_value_try (parser, "proportional-nums", "tabular-nums", NULL); + if (values[n_values]) + { + n_values++; + spacing = TRUE; + } + } + if (!fraction) + { + values[n_values] = _gtk_css_ident_value_try (parser, "diagonal-fractions", "stacked-fractions", NULL); + if (values[n_values]) + { + n_values++; + fraction = TRUE; + } + } + if (!ordinal) + { + values[n_values] = _gtk_css_ident_value_try (parser, "ordinal", NULL); + if (values[n_values]) + { + n_values++; + ordinal = TRUE; + } + } + if (!zero) + { + values[n_values] = _gtk_css_ident_value_try (parser, "slashed-zero", NULL); + if (values[n_values]) + { + n_values++; + zero = TRUE; + } + } + if (old_n == n_values) + { + _gtk_css_parser_error (parser, "Not a valid value"); + return NULL; + } + } while (!value_is_done_parsing (parser)); + + value = _gtk_css_array_value_new_from_array (values, n_values); + } + + return value; +} + static GtkCssValue * box_shadow_value_parse (GtkCssStyleProperty *property, GtkCssParser *parser) @@ -1174,6 +1253,14 @@ _gtk_css_style_property_init_properties (void) parse_font_variant_caps, NULL, _gtk_css_ident_value_new ("normal")); + gtk_css_style_property_register ("font-variant-numeric", + GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC, + G_TYPE_NONE, + 0, + GTK_CSS_AFFECTS_TEXT | GTK_CSS_AFFECTS_TEXT_ATTRS, + parse_font_variant_numeric, + NULL, + _gtk_css_array_value_new (_gtk_css_ident_value_new ("normal"))); gtk_css_style_property_register ("text-shadow", GTK_CSS_PROPERTY_TEXT_SHADOW, G_TYPE_NONE, diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h index 3adb14ca00..5ca7b7aa3a 100644 --- a/gtk/gtkcsstypesprivate.h +++ b/gtk/gtkcsstypesprivate.h @@ -167,6 +167,7 @@ enum { /*< skip >*/ GTK_CSS_PROPERTY_FONT_VARIANT_LIGATURES, GTK_CSS_PROPERTY_FONT_VARIANT_POSITION, GTK_CSS_PROPERTY_FONT_VARIANT_CAPS, + GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC, GTK_CSS_PROPERTY_TEXT_SHADOW, GTK_CSS_PROPERTY_BOX_SHADOW, GTK_CSS_PROPERTY_MARGIN_TOP, -- 2.30.2